[PRIVCMD] Fix ia64 domain creation by abstracting the singleshot mapping check.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 12 Oct 2006 10:44:53 +0000 (11:44 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 12 Oct 2006 10:44:53 +0000 (11:44 +0100)
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c

index c7f2a3632e751a86c0d1031889c040e69c073c03..a17d0769003bb187790ef2e8c084d1acda260c00 100644 (file)
 static struct proc_dir_entry *privcmd_intf;
 static struct proc_dir_entry *capabilities_intf;
 
+static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma)
+{
+#ifndef HAVE_ARCH_PRIVCMD_MMAP
+       if (xchg(&vma->vm_private_data, (void *)1) != NULL)
+               return 0;
+#endif
+       return 1;
+}
+
 static int privcmd_ioctl(struct inode *inode, struct file *file,
                         unsigned int cmd, unsigned long data)
 {
@@ -122,12 +131,10 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
 
                vma = find_vma(mm, msg.va);
                rc = -EINVAL;
-               if (!vma || (msg.va != vma->vm_start) || vma->vm_private_data)
+               if (!vma || (msg.va != vma->vm_start) ||
+                   !privcmd_enforce_singleshot_mapping(vma))
                        goto mmap_out;
 
-               /* Mapping is a one-shot operation per vma. */
-               vma->vm_private_data = (void *)1;
-
                va = vma->vm_start;
 
                for (i = 0; i < mmapcmd.num; i++) {
@@ -190,14 +197,11 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
                if (!vma ||
                    (m.addr != vma->vm_start) ||
                    ((m.addr + (m.num<<PAGE_SHIFT)) != vma->vm_end) ||
-                   vma->vm_private_data) {
+                   !privcmd_enforce_singleshot_mapping(vma)) {
                        up_read(&mm->mmap_sem);
                        return -EINVAL;
                }
 
-               /* Mapping is a one-shot operation per vma. */
-               vma->vm_private_data = (void *)1;
-
                p = m.arr;
                addr = m.addr;
                for (i = 0; i < m.num; i++, addr += PAGE_SIZE, p++) {